﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlamCms.Common;
using System.Xml.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using SlamCms.SharePointServices.Configuration;
using SlamCms.SharePointServices.Lists;

namespace SlamCms.SharePointServices
{
	public static class ListService
	{
		public static ServiceResponse AddItem(string listUrl, ISharePointServiceItem item)
		{
			return default(ServiceResponse);
		}

		public static ServiceResponse DeleteItem(string listUrl, int listRelativeId)
		{
			string listName = listUrl.TrimEnd('/').Substring(listUrl.TrimEnd('/').LastIndexOf("/") + 1);
			return DeleteItem(listUrl, listName, listRelativeId);
		}

		public static ServiceResponse DeleteItem(string listUrl, Guid listId, int listRelativeId)
		{
			return DeleteItem(listUrl, listId.ToString("B"), listRelativeId);
		}

		public static ServiceResponse DeleteItem(string listUrl, string listName, int listRelativeId)
		{
			XElement batchElement = new XElement("Batch", new XAttribute("OnError", "Continue"),
										new XElement("Method", new XAttribute("ID", "1"), new XAttribute("Cmd", "Delete"),
											new XElement("Field", new XAttribute("Name", "ID"), new XText(listRelativeId.ToString()))));

			ListsSoapClient client = ServiceClients.GetListServiceClient(listUrl.TrimEnd('/').Substring(0, listUrl.TrimEnd('/').LastIndexOf('/')));
			OperationContextScope scope = new OperationContextScope(client.InnerChannel);

			if (!String.IsNullOrEmpty(ConfigurationManager.Environment.NetworkCredential.ClaimsAuthenticationType))
			{
				var httpRequestProperty = new HttpRequestMessageProperty();
				httpRequestProperty.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
				OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
			}

			XElement itemsUpdated = client.UpdateListItems(listName, batchElement);
			ServiceResponse response = new ServiceResponse();
			XElement errorTextElement = itemsUpdated.Descendants(XName.Get("ErrorText", "http://schemas.microsoft.com/sharepoint/soap/")).FirstOrDefault();
			if (errorTextElement != null)
			{
				response.MessageCode = ServiceResponseMessageCode.Error;
				response.Message = String.Format("Failed to delete item, {0}.  Error: {1}", listRelativeId, errorTextElement.Value);
			}

			scope.Dispose();

			return response;
		}

		public static ServiceResponse<T> GetItem<T>(string listUrl, int listRelativeId)
		{
			return default(ServiceResponse<T>);
		}

		public static ServiceResponse<T> GetItem<T>(string listUrl, string contentItemId)
		{
			return default(ServiceResponse<T>);
		}

		public static ServiceResponse<IEnumerable<T>> GetItems<T>(string listUrl)
		{
			return default(ServiceResponse<IEnumerable<T>>);
		}

		public static ServiceResponse UpdateItem(string listUrl, int listRelativeId, ISharePointServiceItem item)
		{
			string listName = listUrl.TrimEnd('/').Substring(listUrl.TrimEnd('/').LastIndexOf("/") + 1);
			return UpdateItem(listUrl, listName, listRelativeId, item);
		}

		public static ServiceResponse UpdateItem(string listUrl, Guid listId, int listRelativeId, ISharePointServiceItem item)
		{
			return UpdateItem(listUrl, listId.ToString("B"), listRelativeId, item);
		}

		public static ServiceResponse UpdateItem(string listUrl, string listName, int listRelativeId, ISharePointServiceItem item)
		{
			ServiceResponse<XElement> response = new ServiceResponse<XElement>();
			ListsSoapClient client = ServiceClients.GetListServiceClient(listUrl.TrimEnd('/').Substring(0, listUrl.TrimEnd('/').LastIndexOf('/')));
			OperationContextScope scope = new OperationContextScope(client.InnerChannel);

			if (!String.IsNullOrEmpty(ConfigurationManager.Environment.NetworkCredential.ClaimsAuthenticationType))
			{
				var httpRequestProperty = new HttpRequestMessageProperty();
				httpRequestProperty.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
				OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
			}

			XElement batchElement = null;
			XElement fieldsElement = item.ToServiceXml();

			if (fieldsElement != null && fieldsElement.Descendants("Field").Count() > 0)
			{
				XElement methodElement = new XElement("Method", new XAttribute("ID", "1"),
															   new XAttribute("Cmd", "Update"));

				methodElement.Add(fieldsElement.Descendants("Field").ToArray<XElement>());
				if (!methodElement.Descendants("Field").Any(f => f.Attribute("Name").Value == "ID") && listRelativeId > 0)
				{
					methodElement.Add(new XElement("Field", new XAttribute("Name", "ID"), new XText(listRelativeId.ToString())));
				}

				batchElement = new XElement("Batch", new XAttribute("OnError", "Continue"),
															   new XAttribute("PreCalc", "TRUE"));
				batchElement.Add(methodElement);
			}

			if (batchElement != null)
			{	
				response.Response = client.UpdateListItems(listName, batchElement);
			}

			return response;
		}

		public static ServiceResponse UpdateItemModerationStatus(string listUrl, int listRelativeId, ModerationStatus status)
		{
			string listName = listUrl;
			if (listUrl.Contains("/Lists/"))
			{	
				listName = listUrl.Substring(listUrl.IndexOf("/Lists/") + 7);
				listName = listName.Substring(0, listName.IndexOf('/'));
			}
			else
			{
				listName = listUrl.TrimEnd('/').Substring(listUrl.TrimEnd('/').LastIndexOf("/") + 1);
			}
			return UpdateItemModerationStatus(listUrl, listName, listRelativeId, status);
		}

		public static ServiceResponse UpdateItemModerationStatus(string listUrl, Guid listId, int listRelativeId, ModerationStatus status)
		{
			return UpdateItemModerationStatus(listUrl, listId.ToString("B"), listRelativeId, status);
		}

		public static ServiceResponse UpdateItemModerationStatus(string listUrl, string listName, int listRelativeId, ModerationStatus status)
		{
			ServiceResponse<XElement> response = new ServiceResponse<XElement>();
			string serviceUrl = listUrl;
			if (serviceUrl.Contains("/Lists/"))
			{
				serviceUrl = serviceUrl.Substring(0, serviceUrl.IndexOf("/Lists/") + 1);
			}
			else if (serviceUrl.Contains("/Forms/"))
			{
				serviceUrl = serviceUrl.Substring(0, serviceUrl.IndexOf("/Forms/"));
				serviceUrl = serviceUrl.Substring(0, serviceUrl.TrimEnd('/').LastIndexOf('/'));
			}
			else
			{
				serviceUrl = listUrl.TrimEnd('/').Substring(0, listUrl.TrimEnd('/').LastIndexOf('/'));
			}
			ListsSoapClient client = ServiceClients.GetListServiceClient(serviceUrl);
			OperationContextScope scope = new OperationContextScope(client.InnerChannel);

			if (!String.IsNullOrEmpty(ConfigurationManager.Environment.NetworkCredential.ClaimsAuthenticationType))
			{
				var httpRequestProperty = new HttpRequestMessageProperty();
				httpRequestProperty.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
				OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
			}

			XElement methodElement = new XElement("Method", new XAttribute("ID", "1"),
															   new XAttribute("Cmd", "Moderate"));

			methodElement.Add(new XElement("Field", new XAttribute("Name", "ID"), new XText(listRelativeId.ToString())));
			methodElement.Add(new XElement("Field", new XAttribute("Name", "_ModerationStatus"), new XText(((int)status).ToString())));

			XElement batchElement = new XElement("Batch", new XAttribute("OnError", "Continue"),
															   new XAttribute("PreCalc", "TRUE"),
															   new XAttribute("RootFolder", "TRUE"));
			batchElement.Add(methodElement);
			response.Response = client.UpdateListItems(listName, batchElement);

			return response;
		}
	}
}
